home *** CD-ROM | disk | FTP | other *** search
/ Over 1,000 Windows 95 Programs / Over 1000 Windows 95 Programs (Microforum) (Disc 1).iso / 1263 / fxt.cb < prev    next >
Text File  |  1997-04-18  |  43KB  |  1,262 lines

  1. /*****************************************************************************/
  2. /*
  3.     FXT.CB - BRIEF MACRO FUNCTIONS FOR
  4.  
  5.         FFTN (TM) FORTRAN FUNCTION TREE NAVIGATOR
  6.  
  7.     Copyright (C) Juergen Mueller (J.M.) 1992-1996
  8.     All rights reserved.
  9.  
  10.     You are expressly prohibited from selling this software in any form,
  11.     distributing it with another product, or removing this notice.
  12.  
  13.     Limited permission is given to registered FXT users to modify this
  14.     file for their own personal use only. This file may not be used for any
  15.     purpose other than in conjunction with the FXT software package.
  16.  
  17.     THIS SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND,
  18.     EITHER EXPRESSED OR IMPLIED, INCLUDING, WITHOUT LIMITATION, THE
  19.     IMPLIED WARRANTIES OF MERCHANTIBILITY OR FITNESS FOR A PARTICULAR
  20.     PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE
  21.     PROGRAM AND DOCUMENTATION IS WITH YOU.
  22.  
  23.     written by: Juergen Mueller, Aldingerstrasse 22, D-70806 Kornwestheim,
  24.                 GERMANY
  25.  
  26.     FILE       : FXT.CB
  27.     REVISION   : 27-Apr-1996
  28.                  18:31:07
  29.  */
  30. /*****************************************************************************/
  31.  
  32. #include "dialog.h"     /* include file from original BRIEF DIALOG menus */
  33.  
  34.  
  35. /*****************************************************************************/
  36. /* defines */
  37. /*****************************************************************************/
  38. #define TMPFILE         "FXTFILE.TMP"
  39.  
  40. #define FFTNPROG        "fftn"          /* or "fftn4os2" for OS/2 */
  41.                                         /* or "fftn32" for Windows NT / Windows 95 */
  42.  
  43. #ifdef __OS2__
  44. #define upper(x)        (x)
  45. #endif
  46.  
  47. /*****************************************************************************/
  48. /**** USER macro function prototypes ****/
  49. /*****************************************************************************/
  50. void    fft(void);
  51. void    fftfind(void);
  52. void    fftmenu(void);
  53. void    fftbase(void);
  54. void    fftfilemenu(void);
  55. void    fftxrefmenu(void);
  56. void    fftxrefmenuagain(void);
  57. void    fftdefmenu(void);
  58.  
  59. /*****************************************************************************/
  60. /**** INTERNAL macro function prototypes ****/
  61. /*****************************************************************************/
  62. void    _init(void);            /* initialisation function, called on entry */
  63. void    _fxtmenu_exit(void);
  64. void    _exec_error(int retval, string format, string par1, string par2);
  65. string  _extract_item(void);
  66. void    _fxt(string, string);
  67. void    _fxt_search(string, string, string, int, int);
  68. void    _fxt_edit_file(void);
  69. void    _fxt_locate(void);
  70. void    _fxt_buffers(void);
  71. void    _fxtmenu(string, string);
  72. int     _fft_action(int, ...);
  73. void    _fxtfilemenu(string, string);
  74. int     _fxt_fileaction(int, ...);
  75. void    _fxtxrefmenu(string, string, int);
  76. int     _fxt_xrefaction(int, ...);
  77. void    _fxtdefmenu(string, string);
  78. int     _fxt_defaction(int, ...);
  79. void    _fxt_insert_sorted(string, int, int);
  80.  
  81.  
  82. /*****************************************************************************/
  83. /**** global variables ****/
  84. /*****************************************************************************/
  85. string  fft_base;               /* data base name for fft */
  86.  
  87. string  fxt_loc;                /* resulting file with item location */
  88.  
  89. string  fxt_item;               /* item to search for */
  90. int     fxt_id;                 /* item id */
  91.  
  92. string  fxt_file;               /* target file name */
  93. int     fxt_line;               /* target line, used by registered macro */
  94.  
  95. string  fft_loc;                /* resulting file for menu */
  96. int     fft_menuwidth;          /* horizontal fft menu width */
  97.  
  98. string  fft_files;              /* resulting file for filemenu */
  99. int     fft_filemenuwidth;      /* horizontal fft filemenu width */
  100.  
  101. string  fft_xref;                
  102. string  fft_xref_item;
  103. int     fft_xrefmenuwidth;       
  104.  
  105. string  fft_deffile;
  106. string  fft_def_item;
  107. int     fft_defmenuwidth;
  108.  
  109.  
  110. /*****************************************************************************/
  111. /**** macro package initialization function ****/
  112. /*****************************************************************************/
  113. void _init(void)
  114. {
  115.   /* init FFT base with environment */
  116.   fft_base = trim(ltrim(inq_environment("FFTNBASE")));
  117.  
  118.   fxt_loc = "fxt.loc";          /* intermediate file for search results */
  119.   fft_loc = "fft.loc";          /* used for function menu */
  120.   fft_files = "fft_file.loc";   /* used for function file menu */
  121.   fft_xref = "fft_xref.loc";
  122.   fft_xref_item = "";
  123.   fft_deffile = "fft_def.loc";
  124.   fft_def_item = "";
  125.  
  126.   /* register macro to delete temporary files on exit from BRIEF */
  127.   register_macro(5, "_fxtmenu_exit");
  128. }
  129.  
  130. /*****************************************************************************/
  131. /* registered macro to perform actions on exit of BRIEF or */
  132. /* if changes of database names have happened */
  133. /*****************************************************************************/
  134. void _fxtmenu_exit(void)
  135. {
  136.   if (exist(fft_loc))
  137.     del(fft_loc);
  138.  
  139.   if (exist(fft_files))
  140.     del(fft_files);
  141.  
  142.   if (exist(fft_xref))
  143.     del(fft_xref);
  144.  
  145.   if (exist(fft_deffile))
  146.     del(fft_deffile);
  147. }
  148.  
  149. /*****************************************************************************/
  150. /**** user callable macros ****/
  151. /*****************************************************************************/
  152. void fft(void)                  /* find function */
  153. {
  154.   _fxt(FFTNPROG, fft_base);     /* do function retrieval */
  155. }
  156.  
  157. void fftfind(void)              /* find user defined item */
  158. {
  159.   string item;
  160.  
  161.   get_parm(NULL, item, "FFT function name: ", 50);
  162.   item = compress(trim(ltrim(item)));
  163.  
  164.   if (strlen(item))
  165.     _fxt_search(FFTNPROG, fft_base, item, 0, 0);
  166. }
  167.  
  168. void fftmenu(void)              /* build function menu */
  169. {
  170.   _fxtmenu(FFTNPROG, fft_base);
  171. }
  172.  
  173. void fftbase(void)              /* set FFT database name */
  174. {
  175.   get_parm(NULL, fft_base, "FFT database name: ", 50, fft_base);
  176.   fft_base = trim(ltrim(fft_base));
  177.   _fxtmenu_exit();              /* delete menu files */
  178. }
  179.  
  180. void fftfilemenu(void)          /* build FFT file menu */
  181. {
  182.   _fxtfilemenu(FFTNPROG, fft_base);
  183. }
  184.  
  185. void fftxrefmenu(void)          /* build function cross reference menu */
  186. {
  187.   _fxtxrefmenu(FFTNPROG, fft_base, 1);
  188. }
  189.  
  190. void fftxrefmenuagain(void)     /* rebuild menu for previous item */
  191. {
  192.   _fxtxrefmenu(FFTNPROG, fft_base, 0);
  193. }
  194.  
  195. void fftdefmenu(void)
  196. {
  197.   _fxtdefmenu(FFTNPROG, fft_base);
  198. }
  199.  
  200. /*****************************************************************************/
  201. /**** internal macro execution functions ****/
  202. /*****************************************************************************/
  203.  
  204. /*****************************************************************************/
  205. /* */
  206. /*****************************************************************************/
  207. void _exec_error(int retval, string format, string par1, string par2)
  208. {
  209.   if (retval >= 100)
  210.     message(format, par1, par2);
  211.   else 
  212.     message("Command execution error (%d)", retval);
  213. }
  214.  
  215. /*****************************************************************************/
  216. /* read search item from current buffer */
  217. /*****************************************************************************/
  218. string _extract_item(void)
  219. {
  220.   int    move_flag, markval, marklen;
  221.   int    start_line, start_col, end_line, end_col;
  222.   string itemname, act_char, tmp_char, fchar, nchar;
  223.  
  224.   fchar = "[$_a-zA-Z]";         /* first character of an identifier */
  225.   nchar = "[$_a-zA-Z0-9]";      /* not first character of an identifier */
  226.  
  227.   if (!(markval = inq_marked(start_line, start_col, end_line, end_col)))
  228.   {                             /* nothing marked, use cursor position */
  229.     if (!search_string(nchar, read(1)))
  230.     {
  231.       message("Invalid cursor position");
  232.       return "";
  233.     }
  234.  
  235.     save_position();            /* save the current position */
  236.     act_char = read(1);         /* read current character */
  237.  
  238.     while (search_string(nchar, act_char))
  239.     {                       /* move backward to first character */
  240.       if (!prev_char(1))
  241.       {
  242.         move_flag = 1;
  243.         break;
  244.       }
  245.  
  246.       act_char = read(1);
  247.     }
  248.  
  249.     if (!move_flag)
  250.       next_char(1);             /* one step forward */
  251.  
  252.     act_char = read(1);         /* read current character */
  253.  
  254.     if (!search_string(fchar, act_char))  /* test first identifier character */
  255.     {
  256.       message("Invalid cursor position");
  257.       return "";
  258.     }
  259.  
  260.     while (search_string(nchar, act_char))
  261.     {
  262.       itemname += act_char;             /* generate identifier name */
  263.       next_char(1);
  264.       act_char = read(1);
  265.     }
  266.  
  267.     restore_position();                 /* restore old position */
  268.   }
  269.   else if (markval == 1)        /* marked area found, read contents in */
  270.   {
  271.     marklen = inq_mark_size();          /* number of characters */
  272.  
  273.     if ((start_line != end_line) || (marklen > 60))
  274.     {
  275.       message("Invalid marked block");
  276.       mark();                           /* remove mark */
  277.       return "";
  278.     }
  279.  
  280.     save_position();                    /* save the current position */
  281.     move_abs(start_line, start_col);
  282.  
  283.     while (marklen--)                   /* read marked block */
  284.     {
  285.       itemname += read(1);
  286.       next_char(1);
  287.     }
  288.  
  289.     restore_position();                 /* restore old position */
  290.     mark();                             /* remove mark */
  291.   }
  292.   else
  293.   {                                     /* markval not 0 or 1, error */
  294.     message("Invalid cursor position");
  295.     return "";
  296.   }
  297.  
  298.   if (index(itemname, "\t"))            /* exchange tabs with blanks */
  299.   {
  300.     act_char = "";                      /* temporary storage location */
  301.     end_col = strlen(itemname);
  302.  
  303.     for (start_col = 1; start_col <= end_col; ++start_col)
  304.     {
  305.       tmp_char = substr(itemname, start_col, 1);
  306.       act_char += (tmp_char == "\t") ? " " : tmp_char;
  307.     }
  308.  
  309.     itemname = act_char;                /* restore processed name */
  310.   }
  311.  
  312.   return compress(ltrim(trim(itemname)));       /* compress whitespace */
  313. }
  314.  
  315. /*****************************************************************************/
  316. /* perform data base search with item from current buffer */
  317. /*****************************************************************************/
  318. void _fxt(string fxt_func,      /* fxt function to perform */
  319.           string fxt_base       /* fxt base to search */
  320.          )
  321. {
  322.   string itemname;
  323.  
  324.   itemname = _extract_item();
  325.  
  326.   if (strlen(itemname))
  327.     _fxt_search(fxt_func, fxt_base, itemname, 0, 1);  /* do database search */
  328. }
  329.  
  330. /*****************************************************************************/
  331. /* the database retrieval function */
  332. /*****************************************************************************/
  333. void _fxt_search(string fxt_func,               /* fxt action to perform */
  334.                  string fxt_base,               /* fxt base name to search */
  335.                  string itemname,               /* item to search for */
  336.                  int itemid,                    /* item id */
  337.                  int uflag                      /* underline flag */
  338.                 )
  339. {  
  340.   int    old_buffer, loc_buffer, dos_ret;
  341.   string act_char, linestring, cmd;
  342.  
  343.   /* test for function search and identifier with leading underline */
  344.   if ((fxt_func == FFTNPROG) && uflag && (substr(itemname, 1, 1) == "_"))
  345.   {
  346.     inq_names(NULL, act_char, NULL);    /* get file extension */
  347.     act_char = lower(act_char);
  348.  
  349.     /* test, if we are inside of an assembler file: extension "asm" or "s" */
  350.     if ((act_char == "asm") || (act_char == "s"))
  351.     {                                   /* prompt user for choice */
  352.       get_parm(NULL, act_char, "Remove leading underline before search [y/n]? ", 1, "y");
  353.  
  354.       if (lower(act_char) == "y")
  355.         itemname = substr(itemname, 2); /* remove leading underline */
  356.     }
  357.   }
  358.  
  359.   message("Searching for '%s'", itemname);      /* show what's going on */
  360.  
  361.   /* DATABASE SEARCH */
  362.   /* build command line string, the following arguments are used: */
  363.   /* -b: batch mode */
  364.   /* -f: database name */
  365.   /* -r: record id number */
  366.   sprintf(cmd, "%s -b -r%d ", fxt_func, itemid);
  367.  
  368.   if (strlen(fxt_base))
  369.     cmd += "-f" + fxt_base + " ";
  370.  
  371.   if (index(itemname, " "))             /* if itemname is more than one word */
  372.     cmd += "\"" + itemname + "\"";      /* quote itemname */
  373.   else
  374.     cmd += itemname;
  375.  
  376.   cmd += " >&" + fxt_loc;
  377.   dos_ret = dos(cmd);           /* look for reqested identifier in database */
  378.  
  379.   if (dos_ret == 102)           /* item found, but database not up-to-date */
  380.     get_parm(NULL, act_char, "Database not up-to-date! (press any key)", 1);
  381.   else if (dos_ret != 101)
  382.   {                                             /* item not found */
  383.     _exec_error(dos_ret, "%s '%s' not found", "Function", itemname);
  384.     del(fxt_loc);                               /* delete file */
  385.     return;                                     /* and return */
  386.   }
  387.  
  388.   /* item found, prepare for opening the related source file */ 
  389.   old_buffer = inq_buffer();            /* read result from file */
  390.   loc_buffer = create_buffer(fxt_loc, fxt_loc, 1);
  391.  
  392.   if (!loc_buffer)                      /* if file buffer not present */
  393.     return;                             /* return */
  394.  
  395.   set_buffer(loc_buffer);               /* change working buffer */
  396.   act_char = read(1);                   /* read filename from buffer */
  397.  
  398.   if (act_char == "\n")                 /* file empty ? */
  399.   {
  400.     set_buffer(old_buffer);             /* restore old buffer */
  401.     delete_buffer(loc_buffer);          /* delete working buffer */
  402.     del(fxt_loc);                       /* delete file */
  403.     message("%s '%s' not defined", "Function", itemname);
  404.     return;
  405.   }
  406.  
  407.   fxt_file = "";                        /* initialize file name */
  408.   fxt_line = 1;                         /* initialize line number */
  409.  
  410.   while (!index(" ", act_char))         /* loop over file name */
  411.   {
  412.     fxt_file += act_char;
  413.     next_char(1);
  414.     act_char = read(1);
  415.   }
  416.  
  417.   next_char(1);                         /* skip blank */
  418.   act_char = read(1);                   /* read line number */
  419.  
  420.   while (!index("\r\n", act_char))      /* loop over line number */
  421.   {
  422.     linestring += act_char;
  423.     next_char(1);
  424.     act_char = read(1);
  425.   }
  426.  
  427.   fxt_line = atoi(linestring);          /* convert to integer */
  428.   set_buffer(old_buffer);               /* restore old buffer */
  429.   delete_buffer(loc_buffer);            /* delete working buffer */
  430.   del(fxt_loc);                         /* delete file */
  431.   _fxt_edit_file();                     /* open file for edit */
  432. }
  433.  
  434. /*****************************************************************************/
  435. /* macro for opening file for edit, executed for every file */
  436. /*****************************************************************************/
  437. void _fxt_edit_file(void)
  438. {
  439.   if (!exist(fxt_file))                /* test if file does exist */
  440.     message("Missing file: %s", fxt_file);     /* if not, just give message */
  441.   else
  442.   {                                     /* file exists */
  443.     message("");                        /* clear message area */
  444.     _fxt_buffers();                     /* look for requested file buffer */
  445.  
  446.     register_macro(6, "_fxt_locate");   /* register macro for "edit_file()" */
  447.     edit_file(fxt_file);                /* display requested file */
  448.     unregister_macro(6, "_fxt_locate"); /* unregister macro */
  449.   }
  450. }
  451.  
  452. /*****************************************************************************/
  453. /* registered macro for invocation of "edit_file()" */
  454. /*****************************************************************************/
  455. void _fxt_locate(void)
  456. {
  457.   goto_line(fxt_line);                  /* go to line with searched item */
  458.   refresh();                            /* redraw window */
  459. }
  460.  
  461. /*****************************************************************************/
  462. /* check all buffers if requested file is already in buffer list */
  463. /*****************************************************************************/
  464. void _fxt_buffers(void)
  465. {
  466.   int    curr_buf, old_buf;
  467.   string filename;
  468.  
  469.   old_buf = inq_buffer();               /* actual working buffer */
  470.   curr_buf = old_buf;                   /* remember actual buffer */
  471.  
  472.   do                 /* loop through all buffers to find requested file */
  473.   {
  474.     inq_names(filename);                /* buffer filename */
  475.  
  476.     if (index(upper(filename), upper(fxt_file)))
  477.     {
  478.       goto_line(fxt_line);              /* buffer is present, go to line */
  479.       refresh();                        /* redraw window */
  480.       break;                            /* stop looping */
  481.     }
  482.  
  483.     curr_buf = next_buffer();           /* get next buffer */
  484.     set_buffer(curr_buf);               /* make buffer active */
  485.   } while (curr_buf != old_buf);        /* loop through all buffers */
  486.  
  487.   if (curr_buf != old_buf)              /* if current buffer has changed */
  488.     set_buffer(old_buf);                /* restore first buffer */
  489. }
  490.  
  491. /*****************************************************************************/
  492. /* dialog menu generation front end for fxt items */
  493. /*****************************************************************************/
  494. void _fxtmenu(string fxt_func, string fxt_base)
  495. {
  496.   int    menu_buf, old_buf_id, line, width, max_width;
  497.   int    num_lines, num_cols, dos_ret;
  498.   string fxt_param, fxt_action, item, file;
  499.  
  500.     item = "FFT function";      /* FFT function search */
  501.     file = fft_loc;
  502.     max_width = fft_menuwidth;
  503.     fxt_action = "_fft_action"; /* keystroke action */
  504.  
  505.   message("Building %s menu", item);
  506.  
  507.   if (!exist(file))             /* if menu file does not exist, build it */
  508.   {
  509.     /* DATABASE SEARCH */
  510.     if (strlen(fxt_base))
  511.       fxt_param = " -f" + fxt_base + " ";
  512.  
  513.     dos_ret = dos(fxt_func + " -B " + fxt_param + "* >&" + file);
  514.  
  515.     if (dos_ret != 101)
  516.     {
  517.       _exec_error(dos_ret, "No %s found", item, NULL);
  518.       del(file);                        /* delete file */
  519.       return;
  520.     }
  521.  
  522.     max_width = 0;                      /* reset value */
  523.   }
  524.  
  525.   fxt_item = "";                        /* reset variable */
  526.   old_buf_id = inq_buffer();            /* remember actual buffer */
  527.   menu_buf = create_buffer(item, file, 1); /* use generated file with items */
  528.   set_buffer(menu_buf);                 /* make actual buffer */
  529.   top_of_buffer();                      /* go to top */
  530.  
  531.   if (!max_width)               /* if first call, maximum width is unknown */
  532.   {
  533.     while (!inq_position())     /* read every entry to get maximum width */
  534.     {
  535.       message("Building %s menu [#%d]", item, ++line);
  536.       fxt_item = trim(read());  /* read item */
  537.       fxt_item = substr(fxt_item, 1, rindex(fxt_item, "\t") - 1);
  538.       width = strlen(fxt_item);
  539.  
  540.       if (width > 1)
  541.       {
  542.         if (width > max_width)
  543.           max_width = width;    /* store maximum */
  544.       }
  545.  
  546.       end_of_line();            /* go til end of line and ... */
  547.       next_char(1);             /* wrap around end of line */
  548.     }
  549.  
  550.       fft_menuwidth = max_width;
  551.   }
  552.   else                          /* consecutive call, perform default action */
  553.   {
  554.     end_of_buffer();            /* go to end of buffer */
  555.     next_char(1);               /* go one character beyond the end because */
  556.                                 /* it must be one line more than items */
  557.   }
  558.  
  559.   inq_position(line);           /* get current position */
  560.   top_of_buffer();              /* go to top of buffer */
  561.   fxt_item = "";                /* reset variable */
  562.   fxt_id = 0;
  563.  
  564.   if ((line > 1) && max_width)  /* if any entries found */
  565.   {                             /* start building dialog menu */
  566.     tabs(132);                  /* set new tab size to split informations */
  567.     inq_screen_size(num_lines, num_cols);
  568.  
  569.     if ((line += 3) > (num_lines - 5))
  570.       line = num_lines - 5;
  571.  
  572.     if ((max_width += 2) < 15)
  573.       max_width = 15;
  574.  
  575.     if (max_width >= num_cols - 3)
  576.       max_width = num_cols - 3;
  577.  
  578.     max_width = (max_width + 1) / 2;    /* calculate menu window sizes */
  579.     num_cols = (num_cols + 1 ) / 2;
  580.  
  581.     set_buffer(old_buf_id);             /* restore old buffer */
  582.  
  583.     /* call dialog menu processing function */
  584.     _process_menu(num_cols - max_width,
  585.                   line,
  586.                   num_cols + max_width,
  587.                   3,
  588.                   NULL,
  589.                   "",
  590.                   NULL,
  591.                   menu_buf,             /* buffer to use for dialog menu */
  592.                   fxt_action,           /* function to perform on keystroke */
  593.                   TRUE
  594.                  );
  595.   }
  596.   else                                  /* no entries found */
  597.   {
  598.     set_buffer(old_buf_id);             /* restore old buffer */
  599.     message("No %s found", item);
  600.   }
  601.  
  602.   delete_buffer(menu_buf);              /* delete buffer from list */
  603.  
  604.   if (strlen(fxt_item))                 /* if item selected from menu */
  605.     _fxt_search(fxt_func, fxt_base, fxt_item, fxt_id, 0); /* search and display item */
  606. }
  607.  
  608. /*****************************************************************************/
  609. /* registered macro to perform fft actions for menu keystrokes */
  610. /*****************************************************************************/
  611. int _fft_action(int event_type, ...)
  612. {
  613.   string button_text;
  614.  
  615.   get_parm(NULL, event_type);
  616.  
  617.   switch (event_type)
  618.   {
  619.     case DIALOG_PICK_MENU:
  620.     case DIALOG_F10:
  621.     {
  622.       get_parm(2, button_text);         /* get item name to search for */
  623.       fxt_item = substr(button_text, 1, rindex(button_text, "\t") - 1);
  624.       fxt_id = atoi(substr(button_text, rindex(button_text, "\t") + 1));
  625.       _dialog_esc();                    /* leave menu procedure */
  626.     }
  627.   }
  628.  
  629.   returns(TRUE);
  630. }
  631.  
  632. /*****************************************************************************/
  633. /* dialog menu generation front end for fxt files */
  634. /*****************************************************************************/
  635. void _fxtfilemenu(string fxt_func, string fxt_base)
  636. {
  637.   int    menu_buf, old_buf_id, line, width, max_width;
  638.   int    num_lines, num_cols, dos_ret;
  639.   string fxt_param, item, file;
  640.  
  641.     item = "FFT file";
  642.     file = fft_files;
  643.     max_width = fft_filemenuwidth;
  644.  
  645.   message("Building %s menu", item);
  646.  
  647.   if (!exist(file))             /* if menu file does not exist, build it */
  648.   {
  649.     /* DATABASE SEARCH */
  650.     if (strlen(fxt_base))
  651.       fxt_param = " -f" + fxt_base + " ";
  652.  
  653.     dos_ret = dos(fxt_func + " -F " + fxt_param + "* >&" + file);
  654.  
  655.     if (dos_ret != 101)
  656.     {
  657.       _exec_error(dos_ret, "No %s found", item, NULL);
  658.       del(file);                        /* delete file */
  659.       return;
  660.     }
  661.  
  662.     max_width = 0;                      /* reset value */
  663.   }
  664.  
  665.   fxt_item = "";                        /* reset variable */
  666.   old_buf_id = inq_buffer();            /* remember actual buffer */
  667.   menu_buf = create_buffer(item, file, 1); /* use generated file with items */
  668.   set_buffer(menu_buf);                 /* make actual buffer */
  669.   top_of_buffer();                      /* go to top */
  670.  
  671.   if (!max_width)               /* if first call, maximum width is unknown */
  672.   {
  673.     while (!inq_position())     /* read every entry to get maximum width */
  674.     {
  675.       message("Building %s menu [#%d]", item, ++line);
  676.       fxt_item = trim(read());  /* read item */
  677.       width = strlen(fxt_item);
  678.  
  679.       if (width > 1)
  680.       {
  681.         if (width > max_width)
  682.           max_width = width;    /* store maximum */
  683.       }
  684.  
  685.       end_of_line();            /* go til end of line and ... */
  686.       next_char(1);             /* wrap around end of line */
  687.     }
  688.  
  689.       fft_filemenuwidth = max_width;
  690.   }
  691.   else                          /* consecutive call, perform default action */
  692.   {
  693.     end_of_buffer();            /* go to end of buffer */
  694.     next_char(1);               /* go one character beyond the end because */
  695.                                 /* it must be one line more than items */
  696.   }
  697.  
  698.   inq_position(line);           /* get current position */
  699.   top_of_buffer();              /* go to top of buffer */
  700.   fxt_item = "";                /* reset variable */
  701.  
  702.   if ((line > 1) && max_width)  /* if any entries found */
  703.   {                             /* start building dialog menu */
  704.     tabs(132);                  /* set new tab size to split informations */
  705.     inq_screen_size(num_lines, num_cols);
  706.  
  707.     if ((line += 3) > (num_lines - 5))
  708.       line = num_lines - 5;
  709.  
  710.     if ((max_width += 2) < 15)
  711.       max_width = 15;
  712.  
  713.     if (max_width >= num_cols - 3)
  714.       max_width = num_cols - 3;
  715.  
  716.     max_width = (max_width + 1) / 2;    /* calculate menu window sizes */
  717.     num_cols = (num_cols + 1 ) / 2;
  718.  
  719.     set_buffer(old_buf_id);             /* restore old buffer */
  720.  
  721.     /* call dialog menu processing function */
  722.     _process_menu(num_cols - max_width,
  723.                   line,
  724.                   num_cols + max_width,
  725.                   3,
  726.                   NULL,
  727.                   "",
  728.                   NULL,
  729.                   menu_buf,             /* buffer to use for dialog menu */
  730.                   "_fxt_fileaction",    /* function to perform on keystroke */
  731.                   TRUE
  732.                  );
  733.   }
  734.   else                                  /* no entries found */
  735.   {
  736.     set_buffer(old_buf_id);             /* restore old buffer */
  737.     message("No %s found", item);
  738.   }
  739.  
  740.   delete_buffer(menu_buf);              /* delete buffer from list */
  741.  
  742.   if (strlen(fxt_item))                 /* if item selected from menu */
  743.   {
  744.     fxt_line = 1;
  745.     fxt_file = fxt_item;
  746.     _fxt_edit_file();                   /* open file for edit */
  747.   }
  748. }
  749.  
  750. /*****************************************************************************/
  751. /* registered macro to perform actions for menu keystrokes */
  752. /*****************************************************************************/
  753. int _fxt_fileaction(int event_type, ...)
  754. {
  755.   string button_text;
  756.  
  757.   get_parm(NULL, event_type);
  758.  
  759.   switch (event_type)
  760.   {
  761.     case DIALOG_PICK_MENU:
  762.     case DIALOG_F10:
  763.     {
  764.       get_parm(2, button_text);         /* get item name to search for */
  765.       fxt_item = trim(read());
  766.       _dialog_esc();                    /* leave menu procedure */
  767.     }
  768.   }
  769.  
  770.   returns(TRUE);
  771. }
  772.  
  773. /*****************************************************************************/
  774. /* dialog menu generation front end for fxt items */
  775. /*****************************************************************************/
  776. void _fxtxrefmenu(string fxt_func, string fxt_base, int first)
  777. {
  778.   int    menu_buf, dst_buf, old_buf_id, line, width, max_width;
  779.   int    num_lines, num_cols, dos_ret;
  780.   string fxt_param, item, file, act_char;
  781.  
  782.     item = "FFT";
  783.     fxt_item = fft_xref_item;
  784.     file = fft_xref;
  785.     max_width = fft_xrefmenuwidth;
  786.  
  787.   if (first)
  788.   {
  789.     fxt_item = _extract_item();
  790.  
  791.     if (!strlen(fxt_item))
  792.       return;
  793.  
  794.       fft_xref_item = fxt_item;
  795.  
  796.     if (exist(file))
  797.       del(file);                /* delete file */
  798.  
  799.     max_width = 0;              /* reset value */
  800.   }
  801.   else if (!strlen(fxt_item))
  802.   {
  803.     message("No %s item specified", item);
  804.     return;
  805.   }
  806.  
  807.   message("Building %s reference menu", item);
  808.  
  809.   if (!exist(file))             /* if menu file does not exist, build it */
  810.   {
  811.     /* DATABASE SEARCH */
  812.     if (strlen(fxt_base))
  813.       fxt_param = "-f" + fxt_base + " ";
  814.  
  815.     if (index(fxt_item, " "))
  816.       act_char = "\"" + fxt_item + "\"";        /* quote the string */
  817.     else
  818.       act_char = fxt_item;
  819.  
  820.     /* perform database search for cross references of item */
  821.     dos_ret = dos(fxt_func + " " + fxt_param + "-R" + act_char + " >&" + file);
  822.  
  823.     if (dos_ret != 101)
  824.     {
  825.       message("No %s references for '%s' found", item, fxt_item);
  826.       del(file);                        /* delete file */
  827.       return;
  828.     }
  829.  
  830.     /* sort file names */
  831.     old_buf_id = inq_buffer();          /* remember actual buffer */
  832.     menu_buf = create_buffer(fxt_item, file, 1); /* use generated file with items */
  833.     set_buffer(menu_buf);               /* make actual buffer */
  834.     top_of_buffer();                    /* go to top */
  835.     dst_buf = create_buffer(TMPFILE, TMPFILE, 1);
  836.     max_width = 0;                      /* reset values */
  837.     line = 0;
  838.  
  839.     while (!inq_position())
  840.     {
  841.       /* read line and insert it in sorted order */
  842.       fxt_item = read();        /* read line from source buffer */
  843.       delete_line();            /* and delete this line */
  844.       set_buffer(dst_buf);      /* switch to destination buffer */
  845.       _fxt_insert_sorted(fxt_item, 1, line);    /* insert sorted */
  846.       set_buffer(menu_buf);     /* switch back to source buffer */
  847.  
  848.       /* calculate line length */
  849.       width = strlen(substr(fxt_item, 1, rindex(fxt_item, "\t") - 1));
  850.  
  851.       if (width > 1)
  852.       {
  853.         if (width > max_width)
  854.           max_width = width;    /* store maximum */
  855.       }
  856.  
  857.       /* increment counter and show message */
  858.       message("Building %s reference menu [#%d]", item, ++line);
  859.     }
  860.  
  861.     /* store maximum line length for next call */
  862.       fft_xrefmenuwidth = max_width;
  863.  
  864.     /* destination buffer contains the sorted source buffer */
  865.     /* ... now copy destination back to source buffer */
  866.     set_buffer(dst_buf);                /* switch to destination buffer */
  867.     end_of_buffer();                    /* go to end of buffer */
  868.     inq_position (num_lines, num_cols); /* get buffer end location */
  869.     set_buffer(menu_buf);               /* switch to menu buffer */
  870.     top_of_buffer();                    /* go to buffer start */
  871.     transfer(dst_buf, 1, 1, num_lines, num_cols);       /* transfer buffer */
  872.     write_buffer();                     /* write buffer to disk */
  873.     del(substr(file, 1, rindex(file, "."))  + "BAK");   /* delete backup */
  874.     delete_buffer(dst_buf);             /* delete destination buffer */
  875.     del(TMPFILE);                       /* delete destination file */
  876.   }
  877.   else          /* menu file exists, we have just to get the file */
  878.   {
  879.     old_buf_id = inq_buffer();            /* remember actual buffer */
  880.     menu_buf = create_buffer(fxt_item, file, 1); /* use generated file with items */
  881.     set_buffer(menu_buf);                 /* make actual buffer */
  882.   }
  883.  
  884.   end_of_buffer();              /* go to end of buffer */
  885.   next_char(1);                 /* go one character beyond the end because */
  886.                                 /* it must be one line more than items */
  887.   inq_position(line);           /* get current position */
  888.   top_of_buffer();              /* go to top of buffer */
  889.   fxt_file = "";                /* reset variable */
  890.   fxt_line = 0;
  891.  
  892.   if ((line > 1) && max_width)  /* if any entries found */
  893.   {                             /* start building dialog menu */
  894.     tabs(max_width + 3);        /* set new tab size to split informations */
  895.     inq_screen_size(num_lines, num_cols);
  896.  
  897.     if ((line += 3) > (num_lines - 5))
  898.       line = num_lines - 5;
  899.  
  900.     if ((max_width += 8) < 15)
  901.       max_width = 15;
  902.  
  903.     if (max_width >= num_cols - 3)
  904.       max_width = num_cols - 3;
  905.  
  906.     max_width = (max_width + 1) / 2;    /* calculate menu window sizes */
  907.     num_cols = (num_cols + 1 ) / 2;
  908.  
  909.     set_buffer(old_buf_id);             /* restore old buffer */
  910.  
  911.     /* call dialog menu processing function */
  912.     _process_menu(num_cols - max_width,
  913.                   line,
  914.                   num_cols + max_width,
  915.                   3,
  916.                   NULL,
  917.                   "",
  918.                   NULL,
  919.                   menu_buf,             /* buffer to use for dialog menu */
  920.                   "_fxt_xrefaction",    /* function to perform on keystroke */
  921.                   TRUE
  922.                  );
  923.   }
  924.   else                                  /* no entries found */
  925.   {
  926.     set_buffer(old_buf_id);             /* restore old buffer */
  927.     message("No %s reference found", item);
  928.   }
  929.  
  930.   delete_buffer(menu_buf);              /* delete buffer from list */
  931.  
  932.   if (strlen(fxt_file))                 /* if item selected from menu */
  933.     _fxt_edit_file();
  934. }
  935.  
  936. /*****************************************************************************/
  937. /* registered macro to perform actions for menu keystrokes */
  938. /*****************************************************************************/
  939. int _fxt_xrefaction(int event_type, ...)
  940. {
  941.   string button_text;
  942.  
  943.   get_parm(NULL, event_type);
  944.  
  945.   switch (event_type)
  946.   {
  947.     case DIALOG_PICK_MENU:
  948.     case DIALOG_F10:
  949.     {
  950.       get_parm(2, button_text);         /* get item name to search for */
  951.       fxt_file = substr(button_text, 1, rindex(button_text, "\t") - 1);
  952.       fxt_line = atoi(substr(button_text, rindex(button_text, "\t") + 1));
  953.       _dialog_esc();                    /* leave menu procedure */
  954.     }
  955.   }
  956.  
  957.   returns(TRUE);
  958. }
  959.  
  960. /*****************************************************************************/
  961. /* dialog menu generation front end for file contents */
  962. /*****************************************************************************/
  963. void _fxtdefmenu(string fxt_func, string fxt_base)
  964. {
  965.   int    menu_buf, dst_buf, old_buf_id, line, width, max_width;
  966.   int    num_lines, num_cols, dos_ret;
  967.   string fxt_param, item, file;
  968.  
  969.     item = "FFT";
  970.     fxt_file = fft_def_item;
  971.     file = fft_deffile;
  972.     max_width = fft_defmenuwidth;
  973.  
  974.   inq_names(fxt_item);
  975.  
  976.   if (!strlen(fxt_item))
  977.     return;
  978.  
  979.   if (!strlen(fxt_file) || (fxt_file != fxt_item))
  980.   {
  981.     fxt_file = fxt_item;
  982.  
  983.       fft_def_item = fxt_file;
  984.  
  985.     if (exist(file))
  986.       del(file);                /* delete file */
  987.  
  988.     max_width = 0;              /* reset value */
  989.   }
  990.  
  991.   message("Building %s file contents menu", item);
  992.  
  993.   if (!exist(file))             /* if menu file does not exist, build it */
  994.   {
  995.     /* DATABASE SEARCH */
  996.     if (strlen(fxt_base))
  997.       fxt_param = "-f" + fxt_base + " ";
  998.  
  999.     /* perform database search for cross references of item */
  1000.     dos_ret = dos(fxt_func + " " + fxt_param + "-D" + fxt_file + " >&" + file);
  1001.  
  1002.     if (dos_ret != 101)
  1003.     {
  1004.       _exec_error(dos_ret, "No %s items in '%s' found", item, fxt_file);
  1005.       del(file);                        /* delete file */
  1006.       return;
  1007.     }
  1008.  
  1009.     /* sort file names */
  1010.     old_buf_id = inq_buffer();          /* remember actual buffer */
  1011.     menu_buf = create_buffer("File contents", file, 1); /* use generated file with items */
  1012.     set_buffer(menu_buf);               /* make actual buffer */
  1013.     top_of_buffer();                    /* go to top */
  1014.     dst_buf = create_buffer(TMPFILE, TMPFILE, 1);
  1015.     max_width = 0;                      /* reset values */
  1016.     line = 0;
  1017.  
  1018.     while (!inq_position())
  1019.     {
  1020.       /* read line and insert it in sorted order */
  1021.       fxt_item = read();        /* read line from source buffer */
  1022.       delete_line();            /* and delete this line */
  1023.       set_buffer(dst_buf);      /* switch to destination buffer */
  1024.       _fxt_insert_sorted(fxt_item, 1, line);    /* insert sorted */
  1025.       set_buffer(menu_buf);     /* switch back to source buffer */
  1026.  
  1027.       /* calculate line length */
  1028.       width = strlen(substr(fxt_item, 1, rindex(fxt_item, "\t") - 1));
  1029.  
  1030.       if (width > 1)
  1031.       {
  1032.         if (width > max_width)
  1033.           max_width = width;    /* store maximum */
  1034.       }
  1035.  
  1036.       /* increment counter and show message */
  1037.       message("Building %s file contents menu [#%d]", item, ++line);
  1038.     }
  1039.  
  1040.     /* store maximum line length for next call */
  1041.       fft_defmenuwidth = max_width;
  1042.  
  1043.     /* destination buffer contains the sorted source buffer */
  1044.     /* ... now copy destination back to source buffer */
  1045.     set_buffer(dst_buf);                /* switch to destination buffer */
  1046.     end_of_buffer();                    /* go to end of buffer */
  1047.     inq_position(num_lines, num_cols);  /* get buffer end location */
  1048.     set_buffer(menu_buf);               /* switch to menu buffer */
  1049.     top_of_buffer();                    /* go to buffer start */
  1050.     transfer(dst_buf, 1, 1, num_lines, num_cols);       /* transfer buffer */
  1051.     write_buffer();                     /* write buffer to disk */
  1052.     del(substr(file, 1, rindex(file, "."))  + "BAK");   /* delete backup */
  1053.     delete_buffer(dst_buf);             /* delete destination buffer */
  1054.     del(TMPFILE);                       /* delete destination file */
  1055.   }
  1056.   else          /* menu file exists, we have just to get the file */
  1057.   {
  1058.     old_buf_id = inq_buffer();            /* remember actual buffer */
  1059.     menu_buf = create_buffer("File contents", file, 1); /* use generated file with items */
  1060.     set_buffer(menu_buf);                 /* make actual buffer */
  1061.   }
  1062.  
  1063.   end_of_buffer();              /* go to end of buffer */
  1064.   next_char(1);                 /* go one character beyond the end because */
  1065.                                 /* it must be one line more than items */
  1066.   inq_position(line);           /* get current position */
  1067.   top_of_buffer();              /* go to top of buffer */
  1068.   fxt_line = 0;
  1069.  
  1070.   if ((line > 1) && max_width)  /* if any entries found */
  1071.   {                             /* start building dialog menu */
  1072.     tabs(132);                  /* set new tab size to split informations */
  1073.     inq_screen_size(num_lines, num_cols);
  1074.  
  1075.     if ((line += 3) > (num_lines - 5))
  1076.       line = num_lines - 5;
  1077.  
  1078.     if ((max_width += 2) < 15)
  1079.       max_width = 15;
  1080.  
  1081.     if (max_width >= num_cols - 3)
  1082.       max_width = num_cols - 3;
  1083.  
  1084.     max_width = (max_width + 1) / 2;    /* calculate menu window sizes */
  1085.     num_cols = (num_cols + 1 ) / 2;
  1086.  
  1087.     set_buffer(old_buf_id);             /* restore old buffer */
  1088.  
  1089.     /* call dialog menu processing function */
  1090.     _process_menu(num_cols - max_width,
  1091.                   line,
  1092.                   num_cols + max_width,
  1093.                   3,
  1094.                   NULL,
  1095.                   "",
  1096.                   NULL,
  1097.                   menu_buf,             /* buffer to use for dialog menu */
  1098.                   "_fxt_defaction",     /* function to perform on keystroke */
  1099.                   TRUE
  1100.                  );
  1101.   }
  1102.   else                                  /* no entries found */
  1103.   {
  1104.     set_buffer(old_buf_id);             /* restore old buffer */
  1105.     message("No %s file contents found", item);
  1106.   }
  1107.  
  1108.   delete_buffer(menu_buf);              /* delete buffer from list */
  1109.  
  1110.   if (fxt_line)                         /* if item selected from menu */
  1111.     _fxt_edit_file();
  1112. }
  1113.  
  1114. /*****************************************************************************/
  1115. /* registered macro to perform actions for menu keystrokes */
  1116. /*****************************************************************************/
  1117. int _fxt_defaction(int event_type, ...)
  1118. {
  1119.   string button_text;
  1120.  
  1121.   get_parm(NULL, event_type);
  1122.  
  1123.   switch (event_type)
  1124.   {
  1125.     case DIALOG_PICK_MENU:
  1126.     case DIALOG_F10:
  1127.     {
  1128.       get_parm(2, button_text);         /* get item name to search for */
  1129.       fxt_line = atoi(substr(button_text, rindex(button_text, "\t") + 1));
  1130.       _dialog_esc();                    /* leave menu procedure */
  1131.     }
  1132.   }
  1133.  
  1134.   returns(TRUE);
  1135. }
  1136.  
  1137. /*****************************************************************************/
  1138. /* function to insert text in lexicographical order, binary search */
  1139. /*****************************************************************************/
  1140. void _fxt_insert_sorted(string to_insert, int top, int bottom)
  1141. {
  1142.   if (top <= bottom)
  1143.   {
  1144.     string line_text;
  1145.     string name_ins, name_tmp;
  1146.     int    line_ins, line_tmp;
  1147.  
  1148.     move_abs(bottom, 1);
  1149.     line_text = read();
  1150.  
  1151.     name_tmp = substr(line_text, 1, rindex(line_text, "\t") - 1);
  1152.     line_tmp = atoi(substr(line_text, rindex(line_text, "\t") + 1));
  1153.     name_ins = substr(to_insert, 1, rindex(to_insert, "\t") - 1);
  1154.     line_ins = atoi(substr(to_insert, rindex(to_insert, "\t") + 1));
  1155.  
  1156.     if (   (line_text != "\n")
  1157.         && (   (name_ins < name_tmp)
  1158.             || ((name_ins == name_tmp) && (line_ins < line_tmp))
  1159.            )
  1160.        )
  1161.     {
  1162.       int middle_line;
  1163.  
  1164.       while (top < bottom)
  1165.       {
  1166.         middle_line = top + ((bottom - top) / 2);
  1167.         move_abs(middle_line, 1);
  1168.  
  1169.         line_text = read();
  1170.         name_tmp = substr(line_text, 1, rindex(line_text, "\t") - 1);
  1171.         line_tmp = atoi(substr(line_text, rindex(line_text, "\t") + 1));
  1172.  
  1173.         if (   (name_ins < name_tmp)
  1174.             || ((name_ins == name_tmp) && (line_ins < line_tmp))
  1175.            )
  1176.           bottom = middle_line - 1;
  1177.         else
  1178.           top = middle_line + 1;
  1179.       }
  1180.  
  1181.       move_abs(top, 1);
  1182.       line_text = read();
  1183.       name_tmp = substr(line_text, 1, rindex(line_text, "\t") - 1);
  1184.       line_tmp = atoi(substr(line_text, rindex(line_text, "\t") + 1));
  1185.  
  1186.       if (   (line_text != "\n")
  1187.           && (   (name_ins > name_tmp)
  1188.               || ((name_ins == name_tmp) && (line_ins > line_tmp))
  1189.              )
  1190.          )
  1191.       {
  1192.         down();
  1193.       }
  1194.     }
  1195.     else if (line_text != "\n")
  1196.       down();
  1197.   }
  1198.   else
  1199.     move_abs(top, 1);
  1200.  
  1201.   insert(to_insert);
  1202. }
  1203.  
  1204. /*****************************************************************************/
  1205. /* extract and search for a cross reference number */
  1206. /*****************************************************************************/
  1207. void fxtsearchxref(void)
  1208. {
  1209.   int    move_flag;
  1210.   string itemname, act_char, nchar;
  1211.  
  1212.   nchar = "[0-9]";
  1213.  
  1214.   if (!search_string(nchar, read(1)))
  1215.   {
  1216.     message("Invalid cursor position");
  1217.     return;
  1218.   }
  1219.  
  1220.   message("");
  1221.   save_position();              /* save the current position */
  1222.   act_char = read(1);           /* read current character */
  1223.  
  1224.   while (search_string(nchar, act_char))
  1225.   {
  1226.     if (!prev_char(1))
  1227.     {
  1228.       move_flag = 1;
  1229.       break;
  1230.     }
  1231.  
  1232.     act_char = read(1);
  1233.   }
  1234.  
  1235.   if (!search_string("[(]", act_char))  /* test first character */
  1236.   {
  1237.     message("Invalid cursor position");
  1238.     restore_position();
  1239.     return;
  1240.   }
  1241.  
  1242.   if (!move_flag)
  1243.     next_char(1);               /* one step forward */
  1244.  
  1245.   act_char = read(1);           /* read current character */
  1246.  
  1247.   while (search_string(nchar, act_char))
  1248.   {
  1249.     itemname += act_char;       /* generate search string */
  1250.     next_char(1);
  1251.     act_char = read(1);
  1252.   }
  1253.  
  1254.   itemname = "(" + itemname + ")";
  1255.   message("Searching reference number %s", itemname);
  1256.   goto_line(1);                 /* go to the beginning */
  1257.   search_fwd(itemname);         /* start search */
  1258.   next_char(1);                 /* one step forward */
  1259. }
  1260.  
  1261. /**** THIS IS THE END THIS IS THE END THIS IS THE END THIS IS THE END ****/
  1262.